#ifndef WRK_H
#define WRK_H
#include "config.h"
// #include "stats.h"
#include "ae.h"
#include "http_parser.h"
#include "units.h"
#include <lua.hpp>
#include <map>
#include <vector>
#include <signal.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "wrk_record.h"
#include "server.h"
#include "include/wrk_core_t.h"

#define RECORD_INTERVAL_MS   1000

class WrkRecord;

class WrkCore {
    public:
        WrkCore();
        ~WrkCore();

        static volatile sig_atomic_t stop;

        static wrk_core_config_t cfg;  

        void do_test(const char *script);

        // void set_stop_flag(sig_atomic_t stop);

        wrk_core_config_t get_core_config();

        static int delay_request(aeEventLoop *loop, long long id, void *data);

        string get_stats();

        static std::string script;
        
    private:
        static wrk_core_thread_t *thread_pool;
        static std::vector<wrk_core_thread_t *> thread_vec;

        long long timecb_worker_thread_schedule_id;
        // long long timecb_worker_thread_record_id;

        static pthread_mutex_t mutex;
        static pthread_cond_t cond;

        const static uint32_t threads; //CPU核心数
        static uint32_t threads_left; //未分配出去的线程

        static uint64_t connections_left; //未分配出去的连接

        static int worker_thread_schedule(aeEventLoop *loop, long long id, void *data);

        static int worker_thread_record(aeEventLoop *loop, long long id, void *data);
        
        void init_envirment();
    
        static char *copy_url_part(char *url, struct http_parser_url *parts, enum http_parser_url_fields field);

        static WrkRecord *record;
        void CreateTimeEvent();

        static struct sock sock;
        static size_t sock_can_readable(int fd);
        static void dump_test_result(lua_State *L, uint64_t start);

        static struct http_parser_settings parser_request_settings;
        static struct http_parser_settings parser_response_settings;

        // http parser callback
        static int on_request_url(http_parser *parser, const char *at, size_t len);
        static int on_request_header_field(http_parser *parser, const char *at, size_t len);
        static int on_request_header_value(http_parser *parser, const char *at, size_t len);
        static int on_request_body(http_parser *parser, const char *at, size_t len);
        static int on_response_complete(http_parser *parser);
        static int on_response_header_field(http_parser *parser, const char *at, size_t len);
        static int on_response_header_value(http_parser *parser, const char *at, size_t len);
        static int on_response_body(http_parser *parser, const char *at, size_t len);

        static void socket_readable(aeEventLoop *loop, int fd, void *data, int mask);
        static void socket_writeable(aeEventLoop *loop, int fd, void *data, int mask);
        static void socket_connected(aeEventLoop *loop, int fd, void *data, int mask);
        static int  reconnect_socket(wrk_core_connection_t *c);
        static int  connect_socket(wrk_core_connection_t *c);

        static int monitor_stop_duration(aeEventLoop *loop, long long id, void *data);

        static void parse_request(wrk_core_connection_t *c);

        static void stop_handler(int sig);

        static wrk_core_model_t  *model_ptr;

        static void set_sock(struct sock sk);

        static void *thread_main(void *arg);
        static void *thread_record(void *arg);



        static int record_rate(aeEventLoop *loop, long long id, void *data);
        static int stop_test(aeEventLoop *loop, long long id, void *data);
        static int next_phase(aeEventLoop *loop, long long id, void *data);
        static void adjust_threads(wrk_core_thread_t *t, uint64_t diff_threads);
        static void adjust_connections(wrk_core_thread_t *t, int64_t diff_connections);

        static void phase_stats_correct(wrk_core_thread_t *t);
        static string record2json(map<string, series> map_nodes);
        
        static void close_thread_connection(wrk_core_thread_t *t);

};




#endif /* WRK_H */
